package teamproject.visualization.gui.behaviors;

import java.awt.AWTEvent;
import java.awt.event.KeyEvent;
import java.util.Enumeration;

import javax.media.j3d.Bounds;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.WakeupCriterion;
import javax.media.j3d.WakeupOnAWTEvent;
import javax.media.j3d.WakeupOnElapsedFrames;
import javax.media.j3d.WakeupOr;

import com.sun.j3d.utils.behaviors.mouse.MouseBehavior;

public class CameraNavigatorBehavior extends MouseBehavior {

	// private float x_angle, y_angle;
	// private float x_factor = 0.01f;
	// private float y_factor = 0.01f;

	private WakeupCriterion[] warray;
	private KeyEvent eventKey;
	private CustomKeyNavigator navi;

	private boolean sawFrame = false;
	private WakeupOnAWTEvent wakeupevent;
	private WakeupCriterion wakeupcriterion;
	private AWTEvent[] events;

	public CameraNavigatorBehavior(TransformGroup target, Bounds bounds) {
		super(target);
		navi = new CustomKeyNavigator(target);
		setSchedulingBounds(bounds);
	}

	@Override
	public void initialize() {
		warray = new WakeupCriterion[3];

		warray[0] = new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED);
		warray[1] = new WakeupOnAWTEvent(KeyEvent.KEY_RELEASED);
		warray[2] = new WakeupOnElapsedFrames(0);

		mouseCriterion = new WakeupOr(warray);
		wakeupOn(mouseCriterion);
	}

	private void processAWTEvents(AWTEvent[] events) {
		for (int i = 0; i < events.length; i++) {
			if (events[i] instanceof KeyEvent) {
				eventKey = (KeyEvent) events[i];
				if (eventKey.getID() == KeyEvent.KEY_PRESSED
						|| eventKey.getID() == KeyEvent.KEY_RELEASED)
					navi.processKeyEvent(eventKey);
			}
			// else if (events[i] instanceof MouseEvent) {
			// eventMouse = (MouseEvent) events[i];
			// if (eventMouse.getID() == MouseEvent.MOUSE_DRAGGED)
			// doProcess(eventMouse);
			// }
		}
	}
	//
	// private void doProcess(MouseEvent evt) {
	// int id;
	// int dx, dy;
	//
	// processMouseEvent(evt);
	// if ((((flags & MANUAL_WAKEUP) == 0))
	// || ((wakeUp) && ((flags & MANUAL_WAKEUP) != 0))) {
	// id = evt.getID();
	// if ((id == MouseEvent.MOUSE_DRAGGED) && !evt.isMetaDown()
	// && !evt.isAltDown()) {
	// x = evt.getX();
	// y = evt.getY();
	//
	// dx = x - x_last;
	// dy = y - y_last;
	//
	// if (!reset) {
	// x_angle = dy * y_factor;
	// y_angle = dx * x_factor;
	//
	// transformX.rotX(x_angle);
	// transformY.rotY(y_angle);
	//
	// transformGroup.getTransform(currXform);
	//
	// Matrix4d mat = new Matrix4d();
	// // Remember old matrix
	// currXform.get(mat);
	//
	// // Translate to origin
	// currXform.setTranslation(new Vector3d(0.0, 0.0, 0.0));
	// if (invert) {
	// currXform.mul(currXform, transformX);
	// currXform.mul(currXform, transformY);
	// } else {
	// currXform.mul(transformX, currXform);
	// currXform.mul(transformY, currXform);
	// }
	//
	// // Set old translation back
	// Vector3d translation = new Vector3d(mat.m03, mat.m13,
	// mat.m23);
	// currXform.setTranslation(translation);
	//
	// // Update xform
	// transformGroup.setTransform(currXform);
	// } else {
	// reset = false;
	// }
	//
	// x_last = x;
	// y_last = y;
	// } else if (id == MouseEvent.MOUSE_PRESSED) {
	// x_last = evt.getX();
	// y_last = evt.getY();
	// }
	// }
	// }

	@Override
	public void processStimulus(Enumeration criteria) {

		while (criteria.hasMoreElements()) {
			wakeupcriterion = (WakeupCriterion) criteria.nextElement();
			if (wakeupcriterion instanceof WakeupOnAWTEvent) {
				wakeupevent = (WakeupOnAWTEvent) wakeupcriterion;
				events = wakeupevent.getAWTEvent();
				processAWTEvents(events);
			} else if (wakeupcriterion instanceof WakeupOnElapsedFrames
					&& eventKey != null) {
				sawFrame = true;
			}
		}

		if (sawFrame)
			navi.integrateTransformChanges();

		wakeupOn(mouseCriterion);
	}
}
